package com.hivekion.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hivekion.common.entity.TreeNode;
import com.hivekion.common.exception.BusinessException;
import com.hivekion.system.domain.SysDictType;
import com.hivekion.system.domain.vo.dict.SysDictTypeCreateVo;
import com.hivekion.system.domain.vo.dict.SysDictTypeModelVo;
import com.hivekion.system.domain.vo.dict.SysDictTypeUpdateVo;
import com.hivekion.system.domain.vo.dict.SysDictTypeViewVo;
import com.hivekion.system.mapper.SysDictTypeMapper;
import com.hivekion.system.service.ISysDictTypeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysDictTypeService extends ServiceImpl<SysDictTypeMapper, SysDictType>
        implements ISysDictTypeService {

    @Override
    public Boolean checkTypeNameUnique(String typeName, String key) {
        LambdaQueryWrapper<SysDictType> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SysDictType::getDictName, typeName);
        if (StringUtils.isNotEmpty(key)) {
            queryWrapper.ne(SysDictType::getId, key);
        }
        List<SysDictType> list = this.list(queryWrapper);
        return list.size() > 0;
    }

    @Override
    public Boolean checkTypeCodeUnique(String typeCode, String key) {
        LambdaQueryWrapper<SysDictType> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SysDictType::getDictCode, typeCode);
        if (StringUtils.isNotEmpty(key)) {
            queryWrapper.ne(SysDictType::getId, key);
        }
        List<SysDictType> list = this.list(queryWrapper);
        return list.size() > 0;
    }

    @Override
    public boolean add(SysDictTypeCreateVo createVo) {
        if (this.checkTypeNameUnique(createVo.getDictName(), "")) {
            throw new BusinessException(500, "分类名称已存在，请重新输入！");
        }
        if (this.checkTypeCodeUnique(createVo.getDictCode(), "")) {
            throw new BusinessException(500, "分类编号已存在，请重新输入！");
        }
        SysDictType dictType = new SysDictType();
        BeanUtils.copyProperties(createVo, dictType);
        return this.save(dictType);
    }

    @Override
    public boolean edit(SysDictTypeUpdateVo updateVo) {
        if (this.checkTypeNameUnique(updateVo.getDictName(), updateVo.getId())) {
            throw new BusinessException(500, "分类名称已存在，请重新输入！");
        }
        if (this.checkTypeCodeUnique(updateVo.getDictCode(), updateVo.getId())) {
            throw new BusinessException(500, "分类编号已存在，请重新输入！");
        }
        SysDictType dictType = this.getById(updateVo.getId());
        BeanUtils.copyProperties(updateVo, dictType);
        return this.save(dictType);
    }

    @Override
    public boolean remove(String key) {
        return this.removeById(key);
    }

    @Override
    public SysDictTypeModelVo get(String key) {
        SysDictType dictType = this.getById(key);
        SysDictTypeModelVo vo = new SysDictTypeModelVo();
        BeanUtils.copyProperties(dictType, vo);
        return vo;
    }

    @Override
    public SysDictTypeModelVo getByCode(String code) {
        LambdaQueryWrapper<SysDictType> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SysDictType::getDictCode, code);
        SysDictType dictType = this.getOne(queryWrapper);
        SysDictTypeModelVo vo = new SysDictTypeModelVo();
        BeanUtils.copyProperties(dictType, vo);
        return vo;
    }

    @Override
    public List<SysDictTypeViewVo> getAll() {
        return this.list().stream()
                .map(
                        item -> {
                            SysDictTypeViewVo vo = new SysDictTypeViewVo();
                            BeanUtils.copyProperties(item, vo);
                            return vo;
                        })
                .collect(Collectors.toList());
    }

    @Override
    public List<TreeNode> getTreeNodes() {
        List<TreeNode> nodes =
                this.list().stream()
                        .sorted(Comparator.comparing(SysDictType::getSortCode))
                        .map(
                                item -> {
                                    TreeNode node = new TreeNode();
                                    node.setChildren(null);
                                    node.setLeaf(true);
                                    node.setValue(item.getId());
                                    node.setTitle(
                                            item.getDictName() + "(" + item.getDictCode() + ")");
                                    node.setKey(item.getDictCode());
                                    return node;
                                })
                        .collect(Collectors.toList());
        return nodes;
    }
}
